feat(token-fundraiser): add pinocchio example - #708
Open
MarkFeder wants to merge 4 commits into
Open
Conversation
Ports the token-fundraiser example to Pinocchio (the anchor example has no native sibling). A maker starts a fundraiser with a token target and a duration; contributors deposit tokens into a PDA-owned vault up to a per-contributor cap while the fundraiser runs. Once the target is met the maker releases the funds; if the fundraiser ends without meeting the target, contributors can refund their deposits. Four instructions (initialize, contribute, check_contributions, refund) over two PDA state accounts, using pinocchio-token / pinocchio-associated-token- account for the vault and transfers, PDA-signed CPIs to move funds out of the vault, and the Clock sysvar for the time-based logic. The two inverted time checks in the anchor example are corrected here (contributions are only accepted while running; refunds only after the fundraiser ends). The litesvm test drives the full lifecycle: the refund path (contribute, warp the clock past the deadline, refund) and the release path (ten contributors reach the target, then the maker releases the funds), controlling the clock to exercise the time branches.
Contributor
Greptile SummaryThe follow-up changes complete the requested fundraiser hardening without leaving a blocking failure from the prior review.
Confidence Score: 5/5The PR appears safe to merge because the previously reported blocking failures are fixed and no blocking failure remains. No blocking failure remains. Important Files Changed
Reviews (4): Last reviewed commit: "token-fundraiser: apply prettier formatt..." | Re-trigger Greptile |
…ded totals contribute skipped the contributor PDA derivation whenever the supplied record was already program-owned, so a signer could credit their transfer to another participant's record: it bypassed the per-contributor cap and left the tokens claimable by that record's owner through refund. The derivation now runs before the branch, for existing and new records alike. check_contributions and refund gated on the vault's token balance. The vault is a standard ATA, so any holder could transfer straight into it and push that balance past the target, releasing the fundraiser and blocking legitimate refunds without any recorded contribution. Both now read current_amount; the release still drains the full vault balance. Adds LiteSVM coverage for both: a contribution into a substituted record is rejected, and a direct vault transfer neither releases the fundraiser nor prevents a refund. Both tests fail against the previous program.
contribute took the contributor bump from instruction data and fed it to create_program_address. Several bumps can yield a valid address for the same seeds, so a contributor could open extra, non-canonical records for themselves and be metered against the per-contributor cap separately on each. Those records were also unrefundable, since refund only ever derives the canonical address. The bump is now derived on-chain with find_program_address and the supplied byte is gone from the instruction data entirely, so there is no longer a caller-controlled input to the derivation. This matches the Anchor version, whose `seeds = [...], bump` constraint likewise derives canonically rather than accepting a bump from the client. Adds a test that a contributor_account which is not the canonical PDA is refused before any record is created.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Pinocchio implementation of the token-fundraiser example (the anchor example has no
nativesibling). A maker starts a fundraiser with a token target and a duration; contributors deposit into a PDA-owned vault up to a per-contributor cap while it runs. If the target is met the maker releases the funds; if the fundraiser ends without meeting it, contributors can refund.This revives a previously-deferred port — its only blocker was that bankrun couldn't execute
Clock::get(). The example now uses litesvm, which runs the Clock, so the time-based logic works and is testable.Instructions
Four instructions over two PDA state accounts (
fundraiser,contributor):Uses
pinocchio-token/pinocchio-associated-token-accountfor the vault and transfers,invoke_signedfor the PDA-authorized transfers, and theClocksysvar for the time logic. The two inverted time checks in the anchor example are corrected here (contributions only while running; refunds only after the end).Test
litesvm+@solana/kit, driving the full lifecycle by controlling the clock:Verified locally:
cargo build-sbf, the litesvm tests,tsc --noEmit, Prettier,cargo fmt --check, Clippy, andpnpm install --frozen-lockfileall clean. (Deploy uses the*.soglob per #702.)AI use: I directed the design (the instruction set, PDA/vault layout, the corrected time logic, the multi-scenario clock-driven test) and verified the token/PDA CPI patterns against the merged
escrowpinocchio example; implementation and tests were written with Claude Code and reviewed by me.